package manager

import (
	"BlazeRider-backend/app/models"
	"encoding/json"
	"hash/fnv"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

// 保留原有结构扩展分片
type EventManager struct {
	shards []*eventShard
}

type eventShard struct {
	mu    sync.RWMutex
	items map[string][]models.LiveEventData
}

// 新增分片初始化逻辑
func NewEventManager() *EventManager {
	shards := make([]*eventShard, 64)
	for i := range shards {
		shards[i] = &eventShard{
			items: make(map[string][]models.LiveEventData),
		}
	}
	return &EventManager{shards: shards}
}

// 保留原有AddEventData方法名，内部改为分片操作
func (m *EventManager) AddEventData(liveRoomID string, eventData models.LiveEventData) {
	shard := m.getShard(liveRoomID)
	shard.mu.Lock()
	defer shard.mu.Unlock()

	// 保持原有append逻辑
	shard.items[liveRoomID] = append(shard.items[liveRoomID], eventData)
}

// 优化后的BroadcastEvents（保留原有方法签名）
func (m *EventManager) BroadcastEvents(liveRoomID string, connManager *ConnectionManager) {
	shard := m.getShard(liveRoomID)
	shard.mu.RLock()
	defer shard.mu.RUnlock()

	events := shard.items[liveRoomID]
	currentTime := time.Now()

	// 保留原有过滤逻辑
	var validEvents []models.LiveEventData
	for _, event := range events {
		if currentTime.Sub(time.UnixMilli(event.Data.Timestamp)) <= 5*time.Minute {
			validEvents = append(validEvents, event)
		}
	}

	// 保持原有发送逻辑
	if conns, ok := connManager.Conns()[liveRoomID]; ok {
		for conn, info := range conns {
			go func(c *websocket.Conn, i ConnInfo) {
				var filtered []models.LiveEventData
				i.mu.RLock()
				for _, e := range validEvents {
					if _, acked := i.ackMsgIds[e.Data.MsgID]; !acked {
						filtered = append(filtered, e)
					}
				}
				i.mu.RUnlock()

				if data, err := json.Marshal(filtered); err == nil {
					c.WriteMessage(websocket.TextMessage, data)
				}
			}(conn, info)
		}
	}
}

// 新增分片逻辑
func (m *EventManager) getShard(roomID string) *eventShard {
	h := fnv.New32a()
	h.Write([]byte(roomID))
	return m.shards[h.Sum32()%64]
}

func (m *EventManager) GetAllAndClear() map[string][]models.LiveEventData {
	result := make(map[string][]models.LiveEventData)

	for _, shard := range m.shards {
		shard.mu.Lock()
		for roomID, events := range shard.items {
			// 复制数据并清空
			if len(events) > 0 {
				result[roomID] = append([]models.LiveEventData(nil), events...)
				delete(shard.items, roomID) // 安全清理方式
			}
		}
		shard.mu.Unlock()
	}
	return result
}

// 新增批量获取方法（不清理数据）
func (m *EventManager) GetAllEvents() map[string][]models.LiveEventData {
	result := make(map[string][]models.LiveEventData)

	for _, shard := range m.shards {
		shard.mu.RLock()
		for roomID, events := range shard.items {
			if len(events) > 0 {
				result[roomID] = append(result[roomID], events...)
			}
		}
		shard.mu.RUnlock()
	}
	return result
}
